package de.dubiel.plung.client;

import com.google.gwt.activity.shared.ActivityManager;
import com.google.gwt.activity.shared.ActivityMapper;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.place.shared.Place;
import com.google.gwt.place.shared.PlaceController;
import com.google.gwt.place.shared.PlaceHistoryHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.web.bindery.event.shared.EventBus;

import de.dubiel.plung.client.gin.ClientGinjector;
import de.dubiel.plung.client.mvp.AppActivityMapper;
import de.dubiel.plung.client.mvp.AppPlaceHistoryMapper;
import de.dubiel.plung.client.pages.MainPage;
import de.dubiel.plung.client.pages.start.StartPlace;
import de.dubiel.plung.shared.dao.User;
import de.dubiel.plung.shared.exception.NoGoogleUserException;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class Plung implements EntryPoint {
    /**
     * The message displayed to the user when the server cannot be reached or
     * returns an error.
     */
    private static final String SERVER_ERROR = "An error occurred while attempting to contact the server. Please check your network "
            + "connection and try again.";

    /**
     * Create a remote service proxy to talk to the server-side Greeting
     * service.
     */
    private final ClientGinjector clientGinjector = GWT.create(ClientGinjector.class);
    private final Place defaultPlace = new StartPlace();
    private MainPage appWidget;

    /**
     * This is the entry point method.
     */
    @Override
    public void onModuleLoad() {
        clientGinjector.getUserService().getUser(Document.get().getURL(), new AsyncCallback<User>() {
            @Override
            public void onSuccess(User user) {
                init(user);
            }

            @Override
            public void onFailure(Throwable caught) {
                if (caught instanceof NoGoogleUserException) {
                    Window.Location.assign(((NoGoogleUserException) caught).getLoginUrl());
                } else {
                    Element loader = RootPanel.get("loader").getElement();
                    loader.getStyle().setBackgroundImage("");
                    loader.getStyle().setColor("red");
                    loader.setInnerHTML(SERVER_ERROR + "<br/><br/>" + caught.getMessage());
                }
            }
        });
    }

    /**
     * Aufbau der Seite.
     */
    private void init(User user) {
        clientGinjector.getUserProvider().set(user);
        EventBus eventBus = clientGinjector.getEventBus();
        PlaceController placeController = clientGinjector.getPlaceController();
        appWidget = new MainPage(clientGinjector);

        // Start ActivityManager for the main widget with our ActivityMapper
        ActivityMapper activityMapper = new AppActivityMapper(clientGinjector);
        ActivityManager activityManager = new ActivityManager(activityMapper, eventBus);
        activityManager.setDisplay(appWidget);

        // Start PlaceHistoryHandler with our PlaceHistoryMapper
        AppPlaceHistoryMapper historyMapper = GWT.create(AppPlaceHistoryMapper.class);
        PlaceHistoryHandler historyHandler = new PlaceHistoryHandler(historyMapper);
        historyHandler.register(placeController, eventBus, defaultPlace);

        RootPanel.get("loader").getElement().removeFromParent();
        RootPanel.get().add(appWidget);
        // Goes to the place represented on URL else default place
        historyHandler.handleCurrentHistory();
    }
}